home *** CD-ROM | disk | FTP | other *** search
/ Gigarom 1 / Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso / FILES / BBS / HERMES / ProtMover6.1.cpt / ASCII / Send.c < prev    next >
Text File  |  1990-06-08  |  6KB  |  254 lines

  1. /*    ASCII Transfer External for Hermes © 1990 By John Raymonds.
  2.  
  3.     Written in THINK C 4.0.1 as an example external for Hermes protocol
  4.     developers.  Use of any code shown below in any program other than
  5.     an external to be used with Hermes requires written permission from
  6.     the author:
  7.     
  8.     John Raymonds
  9.     76174,205 (Compuserve)
  10.     D3885 (AppleLink)
  11.     
  12.     Comments and suggestions are welcome.
  13.     
  14. */
  15.  
  16. #include "Protocol.h"
  17. #include "ASCII.h"
  18.  
  19. extern ProtoRecPtr PRP;
  20. extern ProtoGloPtr PGP;
  21.  
  22. OsErr SendASCII()
  23. {
  24.     OsErr err;
  25.     register ProtoRecPtr prp;
  26.     register ProtoGloPtr pgp;
  27.     int i, c, errCount, conErr, Done;
  28.     pgp = PGP;
  29.     prp = PRP;
  30.     err = noErr;
  31.     conErr = 0;
  32.     if (prp->F.B.transMode != TERMINALMODE) {
  33.         SendString(0L);
  34.         SendString("\pASCII 1.0d6 - Type Control-K to abort,");
  35.         SendString("\pControl-P to pause, and (SPACE) to continue.");
  36.         SendString(0L);
  37.         FlushWrite();
  38.     }
  39.     Done = FALSE;
  40.     while (!Done) {
  41.         errCount = pgp->errCount;
  42.         if (!pgp->DIOP.ioRefNum) {
  43.             if (prp->filesDone < prp->fileCount) {
  44.                 /*    reset the time and count */
  45.                 prp->startTime = TickCount();
  46.                 prp->bytesDone = 0;
  47.                 /*    get the file name */
  48.                 Pstrcpy(pgp->fName, *prp->fList[prp->filesDone].fName);
  49.                 /*    get the file info */
  50.                 pgp->FP.ioCompletion = 0L;
  51.                 pgp->FP.ioNamePtr = pgp->fName;
  52.                 pgp->FP.ioVRefNum = prp->fList[prp->filesDone].vRefNum;
  53.                 pgp->FP.ioFVersNum = 0;
  54.                 pgp->FP.ioFDirIndex = 0;
  55.                 err = PBGetFInfo(&pgp->FP, FALSE);
  56.                 if (!err) {
  57.                     /*    set the byte count */
  58.                     prp->bytesTotal = pgp->FP.ioFlLgLen;
  59.                     if (pgp->FP.ioFlFndrInfo.fdType != 'TEXT') {
  60.                         SendString(0L);
  61.                         SendString("\pThat's not a 'TEXT' file!");
  62.                         pgp->errFatal = NOTTEXT;
  63.                         prp->F.B.stopTrans = TRUE;
  64.                     }
  65.                     else {
  66.                         /*    open the data fork: REMEMBER TO USE READ-ONLY
  67.                             PERMISSION SO OTHERS CAN PLAY WITH THE FILE!
  68.                         */
  69.                         pgp->DIOP.ioCompletion = 0L;
  70.                         pgp->DIOP.ioNamePtr = pgp->fName;
  71.                         pgp->DIOP.ioVRefNum = prp->fList[prp->filesDone].vRefNum;
  72.                         pgp->DIOP.ioVersNum = 0;
  73.                         pgp->DIOP.ioPermssn = fsRdPerm;
  74.                         pgp->DIOP.ioMisc = 0L;
  75.                         err = PBOpen(&pgp->DIOP, FALSE);
  76.                     }
  77.                 }
  78.             }
  79.             else {
  80.                 Done = TRUE;
  81.             }
  82.         }
  83.         else {
  84.             /*    send out a word wrapped line of text */
  85.             Pstrcpy(pgp->lineBuffer, pgp->lineExtra);
  86.             pgp->lineExtra[0] = 0;
  87.             for (;;) {
  88.                 c = readAByte();
  89.                 if ((c == '\r') && (pgp->lastC == '\n')) {
  90.                     c = readAByte();
  91.                 }
  92.                 else if ((c == '\n') && (pgp->lastC == '\r')) {
  93.                     c = readAByte();
  94.                 }
  95.                 pgp->lastC = c;
  96.                 if (c == '\n') {
  97.                     c = '\r';
  98.                 }
  99.                 if (c == '\r') {
  100.                     /*    just write out the line */
  101.                     SendString(pgp->lineBuffer);
  102.                     break;
  103.                 }
  104.                 if (c == '\t') {
  105.                     /*    convert tabs to spaces (tab length of 4) */
  106.                     c = 3-(pgp->lineBuffer[0] & 0x03);
  107.                     for (i = 0; i<c; i++) {
  108.                         Pstrcad(pgp->lineBuffer, ' ');
  109.                         if (pgp->lineBuffer[0] == LINESIZE-1) {
  110.                             break;
  111.                         }
  112.                     }
  113.                     c = ' ';
  114.                 }
  115.                 if (c >= 0) {
  116.                     Pstrcad(pgp->lineBuffer, (char) c);
  117.                     if (pgp->lineBuffer[0] == LINESIZE) {
  118.                         /*    do a word wrap */
  119.                         for (i = LINESIZE+1; i>0; i--) {
  120.                             if (pgp->lineBuffer[i] == ' ') {
  121.                                 break;
  122.                             }
  123.                         }
  124.                         if (i) {
  125.                             /*    break at the space */
  126.                             pgp->lineBuffer[0] = i-1;
  127.                             pgp->lineBuffer[i] = LINESIZE-i;
  128.                             Pstrcpy(pgp->lineExtra, &pgp->lineBuffer[i]);
  129.                         }
  130.                         /*    send out what we have */
  131.                         SendString(pgp->lineBuffer);
  132.                         break;
  133.                     }
  134.                 }
  135.                 if (c == eofErr) {
  136.                     /*    write out the line and finish */
  137.                     SendString(pgp->lineBuffer);
  138.                     /*    finished with this file */
  139.                     prp->F.B.newFile = TRUE;
  140.                     /*    return to Hermes for update */
  141.                     Return(0, &pgp->SSR);
  142.                     /*    bump up the file count AFTER we come back from Hermes */
  143.                     ++prp->filesDone;
  144.                     /*    close the file */
  145.                     PBClose(&pgp->DIOP, FALSE);
  146.                     PBFlushVol(&pgp->DIOP, FALSE);
  147.                     pgp->DIOP.ioRefNum = 0;
  148.                     c = noErr;
  149.                     break;
  150.                 }
  151.             }
  152.             FlushWrite();
  153.             if (c < 0) {
  154.                 err = c;
  155.             }
  156.             if (!err) {
  157.                 /*    check for a pause */
  158.                 c = WaitForChar(0);
  159.                 if (PAUSE(c)) {
  160.                     /*    wait for a continue */
  161.                     do {
  162.                         c = WaitForChar(60);
  163.                         if (c == TIMEOUT) {
  164.                             /*    stop transfer if nothing comes in for a minute */
  165.                             pgp->errFatal = NOCONTINUE;
  166.                             Done = TRUE;
  167.                             break;
  168.                         }
  169.                     } while(!CONTINUE(c));
  170.                 }
  171.                 if (c == ABORT) {
  172.                     PRP->F.B.stopTrans = TRUE;
  173.                     Done = TRUE;
  174.                 }
  175.             }
  176.         }
  177.         if (errCount != pgp->errCount) {
  178.             conErr++;
  179.             if (conErr >= MAXERR) {
  180.                 pgp->errFatal = TOOMANYERR;
  181.             }
  182.         }
  183.         else {
  184.             conErr = 0;
  185.         }
  186.         if (err || prp->F.B.carrierLost) {
  187.             Done = TRUE;
  188.         }
  189.         if (prp->F.B.stopTrans || (conErr >= MAXERR)) {
  190.             Done = TRUE;
  191.         }
  192.     }
  193.     /*    see if the file is still open */
  194.     if (pgp->DIOP.ioRefNum) {
  195.         PBClose(&pgp->DIOP, FALSE);
  196.         PBFlushVol(&pgp->DIOP, FALSE);
  197.     }
  198.     /*    flush any characters still coming in */
  199.     FlushModemInput();
  200.     if (prp->F.B.transMode != TERMINALMODE) {
  201.         SendString(0L);
  202.         SendString(0L);
  203.         SendString("\pASCII Send Finished...");
  204.     }
  205.     FlushWrite();
  206.     /*    we are reserving err for Mac OS errors only...
  207.     
  208.         errFatal is keeping track of any protocol erorrs that may
  209.         make the transfer fail.
  210.     */
  211.     if (!err) {
  212.         if (pgp->errFatal) {
  213.             SetError(pgp->errFatal);
  214.         }
  215.     }
  216.     else {
  217.         SetError(err);
  218.     }
  219.     /*    MAKE SURE WE RETURN WITH A NON-ZERO ERROR CODE!!! */
  220.     if (!err) {
  221.         err = 128;
  222.     }
  223.     return(err);
  224. }
  225.         
  226. int readAByte()
  227. {
  228.     register OsErr err;
  229.     register ProtoGloPtr pgp;
  230.     pgp = PGP;
  231.     if (pgp->rBValid) {
  232.         --pgp->rBValid;
  233.         return((int) pgp->theData[pgp->rBPos++]);
  234.     }
  235.     else {
  236.         /*    read some data into the buffer */
  237.         pgp->DIOP.ioBuffer = (Ptr) &pgp->theData[0];
  238.         pgp->DIOP.ioReqCount = 1024;
  239.         pgp->DIOP.ioPosMode = fsFromMark;
  240.         pgp->DIOP.ioPosOffset = 0;
  241.         err = PBRead(&pgp->DIOP, FALSE);
  242.         if (pgp->DIOP.ioActCount) {
  243.             PRP->bytesDone += pgp->DIOP.ioActCount;
  244.             err = noErr;
  245.         }
  246.         if (err) {
  247.             return(err);
  248.         }
  249.         pgp->rBValid = pgp->DIOP.ioActCount;
  250.         pgp->rBPos = 0;
  251.         return(readAByte());
  252.     }
  253. }
  254.